#ifndef MEASURE_SIZE_TRACKER_FAST_TRIGONOMETRIES_H_
#define MEASURE_SIZE_TRACKER_FAST_TRIGONOMETRIES_H_

#if defined(_MSC_VER)
#pragma once
#endif

#include "boost\math\special_functions\round.hpp"

extern const double kSin[361];
extern const double kCos[361];

class angle_math {
public:
  static int degree(double x) { return boost::math::iround(x*kRadian); }
  static double radian(int x) { return x*kInvRadian; }
  static double radian(double x) { return x*kInvRadian; }
  static int normalize(int x) { int y=x%360; return (y<0)?(y+360):y; }
  static double normalize(double x);
  static int sweep(int s, int e) { return e>=s?(e-s):(e+360-s); }
  static double sweep(double s, double e) { return e>=s?(e-s):(e+360-s); }
  static double angle(double x, double y) { return normalize(kRadian*atan2(y, x)); }
  static bool contain(int a, int s, int e);

public:
  static const double	kPi;
  static const double	kRadian;
  static const double	kInvRadian;
};

class idegree {
public:
  idegree(void) : val(0) {}
  idegree(int val_) : val(val_) {}
  idegree(double val_) : val(boost::math::iround(val_)) {}

public:
  bool contain(int start_angle, int end_angle) const;

public:
  double radian(void) const { return angle_math::radian(val); }
  int normalize(void) const { return angle_math::normalize(val); }

public:
  int val;
};

class simple_math {
public:
  static bool power_of_2(int n) { return (n&(n-1))==0; }

public:
  template<class T> static T square(T x) { return x*x; }

public:
  static const double	kGolden;
  static const double	kGoldenC;
  static const double	kSqrt2;
  static const double	kInvSqrt2;
};

#endif // MEASURE_SIZE_TRACKER_FAST_TRIGONOMETRIES_H_

